# -*- coding: utf-8 -*-
"""
Created on Thu Jan  4 11:39:36 2018

@author:Devin

"""
from collections import Counter
import pandas as pd
import numpy as np

all_col = ['tboxid', 'vin', 'starttime', 'gnsstime', 'gnsslong', 'gnsslat',
       'gnssalt', 'gnsshead', 'gnsssats', 'vehspeed', 'vehrpm', 'vehsyspwrmod',
       'vehgearpos', 'tboxaccelx', 'tboxaccely', 'tboxaccelz', 'vehaccelpos',
       'vehbrakepos', 'vehsteeringangle', 'vehfuelconsumed', 'vehdoorfrontpas',
       'vehdoorfrontdrv', 'vehdoorrearleft', 'vehdoorrearright', 'vehbonnet',
       'vehboot', 'vehwindowfrontleft', 'vehwindowrearleft',
       'vehwindowfrontright', 'vehwindowrearright', 'vehsunroof',
       'vehcruiseactive', 'vehcruiseenabled', 'vehcruisetargetspeed',
       'vehoutsidetemp', 'vehinsidetemp', 'vehac', 'vehacauto',
       'vehaccircdirection', 'vehaccirctype', 'vehacfanspeed',
       'vehacdrvtargettemp', 'vehacpasstargettemp', 'vehseatbeltdrv',
       'vehseatbeltpas', 'vehindlightleft', 'vehindlightright', 'vehsidelight',
       'vehdiplight', 'vehmainlight', 'vehfoglightfront', 'vehfoglightrear',
       'vehwiperswitchfront', 'vehraindetected', 'vehnightdetected',
       'vehfuellev', 'vehbatt', 'vehcoolanttemp', 'vehodo', 'vehdistrollcount',
       'vehhorn', 'vehoilpressurewarning', 'vehmilwarning',
       'vehdrivebywirewarning', 'cellmcc', 'cellmnc', 'cellsignalstrength',
       'cellrat', 'celllac', 'cellcellid', 'cellchanid', 'hdop', 'gpsstatus',
       'partnumber', 'version', 'engineering_model', 'rt_minute_pt',
       'createtime', 'sub_engineering_model', 'c_30_dtcinfomationtcm',
       'c_30_dtcinfomationecm', 'c_30_dtcinfomationbcm', 'pt', 'model']

all_cols = ['vin', 'starttime', 'vehspeed', 'vehrpm', 'vehsyspwrmod',
       'vehgearpos', 'tboxaccelx', 'tboxaccely', 'tboxaccelz', 
       'vehbrakepos','vehfuelconsumed',
       'vehoutsidetemp', 'vehinsidetemp', 'vehac', 'vehacauto', 'vehacfanspeed',
       'vehacdrvtargettemp', 'vehacpasstargettemp','vehsidelight',
       'vehdiplight', 'vehmainlight',
       'vehwiperswitchfront',
       'vehfuellev', 'vehbatt', 'vehcoolanttemp', 'vehodo','ptime']



#globals()['takes'] = pd.read_csv(path+file_tbox[0], sep=',',usecols = all_cols)


class Construction_data():
    '''
    the class of converge of data, default time is day!
    two args need give : df and time
    for df need have common vin at serial time.
    time can give : 'M'/'D'/'H'
    add ptime columns
    return 73 columns data in every VIN
    
    '''
    
    def __init__(self,df,time='D'):
        self.n_power_time_012 = 'n_power_time_012'
        self.n_power_time_12 = 'n_power_time_12'
        self.pm_1 = 'pm_1'
        self.pm_2 = 'pm_2'
        self.pm_3 = 'pm_3'
        self.pm_0 = 'pm_0'
        self.run_time_2k = 'run_time_2k'
        self.run_time_15k = 'run_time_15k'
        self.run_time_3k = 'run_time_3k'
        self.run_time_25k = 'run_time_25k'
        self.run_time_1k = 'run_time_1k'
        self.num_non_p = 'num_non_p'
        self.oil_non_p = 'oil_non_p'
        self.battery_start = 'battery_start'
        self.oil_start = 'oil_start'
        self.battery_avg = 'battery_avg'
        self.battery_11 = 'battery_11'
        self.battery_12 = 'battery_12'
        self.battery_13 = 'battery_13'
        self.battery_14 = 'battery_14'
        self.battery_var = 'battery_var'
        self.battery_max = 'battery_max'
        self.battery_mix4 = 'battery_mix4'
        self.battery_mix1 = 'battery_mix1'
        self.battery_min = 'battery_min'
        self.kurt_v_battery = 'kurt_v_battery'
        self.skew_v_battery = 'skew_v_battery'
        self.avg_temperature_in = 'avg_temperature_in'
        self.avg_temperature_out = 'avg_temperature_out'
        self.starting_num_day = 'starting_num_day'
        self.minutes15_st = '15_minutes_st'
        self.minutes_30_st = '30_minutes_st'
        self.remote_boot_times = 'remote_boot_times'
        self.x_acc = 'x_acc'
        self.y_acc = 'y_acc'
        self.z_acc = 'z_acc'
        self.brakepos_var = 'brakepos_var'
        self.dr_avg_v = 'dr_avg_v'
        self.dr_avg_mile = 'dr_avg_mile'
        self.dr_mile30 = 'dr_mile30'
        self.dr_v30_rate = 'dr_v30_rate'
        self.dr_mile50 = 'dr_mile50'
        self.dr_v0_rate = 'dr_v0_rate'
        self.avg_run_mile = 'avg_run_mile'
        self.avg_run_times = 'avg_run_times'
        self.ac_on_count = 'ac_on_count'
        self.ac_auto_on_count = 'ac_auto_on_count'
        self.fanspeed_avg = 'fanspeed_avg'
        self.fanspeed_var = 'fanspeed_var'
        self.d_temp_avg = 'd_temp_avg'
        self.c_temp_avg = 'c_temp_avg'
        self.side_light_count = 'side_light_count'
        self.dip_light_count = 'dip_light_count'
        self.main_light_count = 'main_light_count'
        self.wiperswitch_avg = 'wiperswitch_avg'
        self.oli_box_avg = 'oli_box_avg'
        self.cool_avg = 'cool_avg'
        self.batt_1 = 'batt_1'
        self.batt_0 = 'batt_0'
        self.mils = 'mils'
        self.acc_seqs_min30_0_rate = 'acc_seqs_min30_0_rate'
        self.acc_seqs_min10_0_rate = 'acc_seqs_min10_0_rate'
        self.acc_seqs_min20_0_rate = 'acc_seqs_min20_0_rate'
        self.max_seq_veh = 'max_seq_veh'
        self.t_time = 't_time'
        self.max_speed = 'max_speed'
        self.total_time_v1_rpm0 = 'total_time_v1_rpm0'
        self.total_time_v1_rpm1 = 'total_time_v1_rpm1'
        self.max_vehrpm = 'max_vehrpm'
        self.t_time_batt12 = 't_time_batt12'
        self.t_time_batt10 = 't_time_batt10'
        self.t_time_batt14 = 't_time_batt14'
        self.purchase_time = 'purchase_time'
        
        self.df = df
        self.time = time
        self.df.starttime = pd.to_datetime(self.df.starttime)
        self.df.ptime = pd.to_datetime(self.df.ptime)
        self.df.index = self.df.starttime
        self.df = self.df.sort_index()
        self.day_index = self.df.to_period(self.time)
        self.day_group = self.day_index.groupby(self.day_index.index)
        
        
    def n_p_time_012(self,g_df):
        vehsyspwrmod_list = list(g_df.loc[:,'vehsyspwrmod'])
        values_counts = Counter(vehsyspwrmod_list)
        return (values_counts[0]+values_counts[1])/len(vehsyspwrmod_list)
    
    def n_p_time_12(self,g_df):
        vehsyspwrmod_list = list(g_df.loc[:,'vehsyspwrmod'])
        values_counts = Counter(vehsyspwrmod_list)
        try:
            return values_counts[1]/values_counts[2]
        except:return 0
        
    def fpm_1(self,g_df):
        vehsyspwrmod_list = list(g_df.loc[:,'vehsyspwrmod'])
        values_counts = Counter(vehsyspwrmod_list)
        return (values_counts[1])/len(vehsyspwrmod_list)
    
    def fpm_0(self,g_df):
        vehsyspwrmod_list = list(g_df.loc[:,'vehsyspwrmod'])
        values_counts = Counter(vehsyspwrmod_list)
        return (values_counts[0])/len(vehsyspwrmod_list)
    
    def fpm_2(self,g_df):
        vehsyspwrmod_list = list(g_df.loc[:,'vehsyspwrmod'])
        values_counts = Counter(vehsyspwrmod_list)
        return (values_counts[2])/len(vehsyspwrmod_list)
    
    def fpm_3(self,g_df):
        vehsyspwrmod_list = list(g_df.loc[:,'vehsyspwrmod'])
        values_counts = Counter(vehsyspwrmod_list)
        return (values_counts[3])/len(vehsyspwrmod_list)
    
    def run_t_2k(self,g_df):
        vehrpm_2k = g_df[g_df.vehrpm < 2000].shape[0]
        try:
            return vehrpm_2k/g_df.shape[0]
        except:return 0
    
    def run_t_1k(self,g_df):
        vehsyspwrmod_list = list(g_df.loc[:,'vehsyspwrmod'])
        values_counts = Counter(vehsyspwrmod_list)
        vehrpm_1k = g_df[g_df.vehrpm < 1000].shape[0]
        try:
            return vehrpm_1k/values_counts[2]
        except:
            return 0
    
    def run_t_15k(self,g_df):
        vehsyspwrmod_list = list(g_df.loc[:,'vehsyspwrmod'])
        values_counts = Counter(vehsyspwrmod_list)
        vehrpm_15k = g_df[g_df.vehrpm < 1500].shape[0]
        try:
            return vehrpm_15k/values_counts[2]
        except:
            return 0
    
    def run_t_25k(self,g_df):
        vehsyspwrmod_list = list(g_df.loc[:,'vehsyspwrmod'])
        values_counts = Counter(vehsyspwrmod_list)
        vehrpm_25k = g_df[g_df.vehrpm < 2500].shape[0]
        try:
            return vehrpm_25k/values_counts[2]
        except:
            return 0
    
    def run_t_3k(self,g_df):
        vehsyspwrmod_list = list(g_df.loc[:,'vehsyspwrmod'])
        values_counts = Counter(vehsyspwrmod_list)
        vehrpm_3k = g_df[g_df.vehrpm < 3000].shape[0]
        try:
            return vehrpm_3k/values_counts[2]
        except:
            return 0
    
  
    def num_n_p(self,g_df):
        ttx = np.array(g_df.starttime)
        c = list(np.diff(ttx)/np.timedelta64(1, 's'))
        c.insert(0,1);g_df.loc[:,'temp'] = c
        start_t = g_df[g_df.temp > 10].starttime.tolist()
        i=0
        if len(start_t) == 0:
            return 0
        for t in start_t:
            diff = float(g_df[g_df.starttime==t].iloc[-1].vehbatt)- float(g_df[g_df.starttime<t].iloc[-1].vehbatt)
            i+=abs(diff)
            pass
        return i/len(start_t)
    
    def oil_n_p(self,g_df):
        ttx = np.array(g_df.starttime)
        c = list(np.diff(ttx)/np.timedelta64(1, 's'))
        c.insert(0,1);g_df.loc[:,'temp'] = c
        start_t = g_df[g_df.temp > 10].starttime.tolist()
        i=0
        if len(start_t) == 0:
            return 0
        for t in start_t:
            diff = float(g_df[g_df.starttime==t].iloc[-1].vehcoolanttemp)- float(g_df[g_df.starttime<t].iloc[-1].vehcoolanttemp)
            i+=abs(diff)
            pass
        return i/len(start_t)
    
    def batt_start(self,g_df):
        ttx = np.array(g_df.starttime)
        c = list(np.diff(ttx)/np.timedelta64(1, 's'))
        c.insert(0,1);g_df.loc[:,'temp'] = c
        start_t = g_df[g_df.temp > 10].starttime.tolist()
        i=0
        if len(start_t) == 0:
            return 0
        for t in start_t:
            diff = float(g_df[g_df.starttime==t].iloc[-1].vehbatt)
            i+=abs(diff)
            pass
        return i/len(start_t)
    
    def oils_start(self,g_df):
        ttx = np.array(g_df.starttime)
        c = list(np.diff(ttx)/np.timedelta64(1, 's'))
        c.insert(0,1);g_df.loc[:,'temp'] = c
        start_t = g_df[g_df.temp > 10].starttime.tolist()
        i=0
        if len(start_t) == 0:
            return 0
        for t in start_t:
            diff = float(g_df[g_df.starttime==t].iloc[-1].vehcoolanttemp)
            i+=abs(diff)
            pass
        return i/len(start_t)
    
    def batt_avg(self,g_df):
        return g_df.vehbatt.mean()
        
    def batt_11(self,g_df):
        vehsyspwrmod_list = list(g_df.loc[:,'vehsyspwrmod'])
        values_counts = Counter(vehsyspwrmod_list)
        if values_counts[2]==0:
            return 0
        else:
            return g_df[g_df.vehbatt < 11].shape[0]/values_counts[2]
        
    def batt_12(self,g_df):
        vehsyspwrmod_list = list(g_df.loc[:,'vehsyspwrmod'])
        values_counts = Counter(vehsyspwrmod_list)
        if values_counts[2]==0:
            return 0
        else:
            return g_df.loc[(g_df['vehbatt']>11)&(g_df['vehbatt']<12)].shape[0]/values_counts[2]  
    
    def batt_13(self,g_df):
        vehsyspwrmod_list = list(g_df.loc[:,'vehsyspwrmod'])
        values_counts = Counter(vehsyspwrmod_list)
        if values_counts[2]==0:
            return 0
        else:
            return g_df.loc[(g_df['vehbatt']>=12)&(g_df['vehbatt']<13)].shape[0]/values_counts[2] 
        
    def batt_14(self,g_df):
        vehsyspwrmod_list = list(g_df.loc[:,'vehsyspwrmod'])
        values_counts = Counter(vehsyspwrmod_list)
        if values_counts[2]==0:
            return 0
        else:
            return g_df.loc[(g_df['vehbatt']>=13)&(g_df['vehbatt']<=19)].shape[0]/values_counts[2] 
    
    def batt_var(self,g_df):
        return g_df.vehbatt.std()
    
    def batt_max(self,g_df):
        return g_df.vehbatt.max()
    
    def batt_mix4(self,g_df):
        return g_df.vehbatt.quantile(0.4)   
    
    def batt_mix1(self,g_df):
        return g_df.vehbatt.quantile(0.1) 
    
    def batt_min(self,g_df):
        return g_df.vehbatt.min() 
    
    def kurt_v_batterys(self,g_df):
        return g_df.vehbatt.kurt()
    
    def skew_v_batterys(self,g_df):
        return g_df.vehbatt.skew()
    
    def avg_temp_in(self,g_df):
        return g_df.vehinsidetemp.mean()
    
    def avg_temp_out(self,g_df):
        return g_df.vehoutsidetemp.mean()
        
    def start_num_day(self,g_df):
        ttx = np.array(g_df.starttime)
        c = list(np.diff(ttx)/np.timedelta64(1, 's'))
        c.insert(0,1);g_df.loc[:,'temp'] = c
        return len(g_df[g_df.temp > 10].starttime.tolist())
    
    def min15_st(self,g_df):
        ttx = np.array(g_df.starttime)
        c = list(np.diff(ttx)/np.timedelta64(1, 's'))
        c.insert(0,1);g_df.loc[:,'temp'] = c
        start_t = g_df[g_df.temp > 10].starttime.tolist()
        i=0
        ax = pd.DataFrame(start_t,columns=['t'])
        tc = [x.total_seconds()/60 for x in ax.diff().dropna().t]
        for t in tc:
            if t < 15:
                i+=1
        return i
    
    def max30_st(self,g_df):
        ttx = np.array(g_df.starttime)
        c = list(np.diff(ttx)/np.timedelta64(1, 's'))
        c.insert(0,1);g_df.loc[:,'temp'] = c
        start_t = g_df[g_df.temp > 10].starttime.tolist()
        i=0
        ax = pd.DataFrame(start_t,columns=['t'])
        tc = [x.total_seconds()/60 for x in ax.diff().dropna().t]
        for t in tc:
            if t > 30:
                i+=1
        return i
        
    def remote_times(self,g_df):
        return g_df.vehbatt.median()
    
    def x_ac(self,g_df):
        return g_df.tboxaccelx.std()
    
    def y_ac(self,g_df):
        return g_df.tboxaccely.std()
    
    def z_ac(self,g_df):
        return g_df.tboxaccelz.std()
        
    def brak_var(self,g_df):
        return g_df.vehbrakepos.std()
        
    def d_avg_v(self,g_df):
        g_1 = g_df[g_df.vehspeed>0]
        return g_1.vehspeed.mean()
    
    def d_avg_mile(self,g_df):
        return g_df.vehodo.iloc[-1]-g_df.vehodo.iloc[0]
    
    def dr_miles30s(self,g_df):
        g_1 = g_df[g_df.vehspeed>0]
        return g_1[g_1.vehspeed<30].shape[0]/3600
    
    def dr_miles50s(self,g_df):
        g_1 = g_df[g_df.vehspeed>0]
        return g_1[g_1.vehspeed<50].shape[0]/3600
    
    def dr_v0_rates(self,g_df):
        g_1 = g_df[g_df.vehspeed>0]
        if g_1.shape[0]==0:
            return 0
        return g_1[g_1.vehspeed<50].shape[0]/g_1.shape[0]
    
    def dr_v30_rates(self,g_df):
        g_1 = g_df[g_df.vehspeed>0]
        if g_1.shape[0]==0:
            return 0
        return g_1[g_1.vehspeed<30].shape[0]/g_1.shape[0]

    def avg_run_time(self,g_df):
        return g_df[g_df.vehsyspwrmod > 0].shape[0]/3600
        
    def ac_on_counts(self,g_df):
        return g_df[g_df.vehac > 0].shape[0]/g_df.shape[0]
    
    def ac_auto_on_counts(self,g_df):
        return g_df[g_df.vehacauto > 0].shape[0]/g_df.shape[0]
    
    def fanspeed_avgs(self,g_df):
        return g_df.vehacfanspeed.mean()
    
    def fanspeed_vars(self,g_df):
        return g_df.vehacfanspeed.std()
        
    def d_temp_avgs(self,g_df):
        g_p = g_df[g_df.vehacdrvtargettemp>0]
        return g_p.vehacdrvtargettemp.mean()
    
    def c_temp_avgs(self,g_df):
        g_p = g_df[g_df.vehacpasstargettemp>0]
        return g_p.vehacpasstargettemp.mean()
    
    def side_light_counts(self,g_df):
        gs = g_df[g_df.vehsidelight>0]
        return gs.shape[0]/g_df.shape[0]
    
    def dip_light_counts(self,g_df):
        return g_df[g_df.vehdiplight > 0].shape[0]/g_df.shape[0]
    
    def main_light_counts(self,g_df):
        return g_df[g_df.vehmainlight > 0].shape[0]/g_df.shape[0]
    
    def wiperswitch_avgs(self,g_df):
        gs = g_df[g_df.vehwiperswitchfront>0]
        return gs.shape[0]/g_df.shape[0]
    
    def oli_box_avgs(self,g_df):
        return g_df.vehfuellev.mean()
        
    
    def cool_avgs(self,g_df):
        return g_df.vehcoolanttemp.mean()
    
    def milss(self,g_df):
        return g_df.vehodo[-1]
    
    def batt_1s(self,g_df):
        return g_df.vehbatt[-1]
    
    def batt_0s(self,g_df):
        return g_df.vehbatt[0]
    
    def acc_seqs_min30_0_rates(self,g_df):
        ttx = np.array(g_df.starttime)
        c = list(np.diff(ttx)/np.timedelta64(1, 's'))
        c.insert(0,1);g_df.loc[:,'temp'] = c
        start_t = g_df[g_df.temp > 10].starttime.tolist()
        if len(start_t) == 0:
            return 0
        elif len(start_t) == 1:
            return 1 
        veh = [];vehs=[]
        for t in start_t:
            veh.append(g_df[g_df.starttime==t].vehodo)
        try:
            for i in range(len(veh)-1):
                if int(veh[i+1])-int(veh[i])<=30:
                    vehs.append(int(veh[i+1])-int(veh[i]))
            return len(vehs)
        except:return 2
    
    def acc_seqs_min20_0_rates(self,g_df):
        ttx = np.array(g_df.starttime)
        c = list(np.diff(ttx)/np.timedelta64(1, 's'))
        c.insert(0,1);g_df.loc[:,'temp'] = c
        start_t = g_df[g_df.temp > 10].starttime.tolist()
        if len(start_t) == 0:
            return 0
        elif len(start_t) == 1:
            return 1 
        veh = [];vehs=[]
        for t in start_t:
            veh.append(g_df[g_df.starttime==t].vehodo)
        try:
            for i in range(len(veh)-1):
                if int(veh[i+1])-int(veh[i])<=20:
                    vehs.append(int(veh[i+1])-int(veh[i]))
            return len(vehs)
        except:return 2
    
    def acc_seqs_min10_0_rates(self,g_df):
        ttx = np.array(g_df.starttime)
        c = list(np.diff(ttx)/np.timedelta64(1, 's'))
        c.insert(0,1);g_df.loc[:,'temp'] = c
        start_t = g_df[g_df.temp > 10].starttime.tolist()
        if len(start_t) == 0:
            return 0
        elif len(start_t) == 1:
            return 1
        veh = [];vehs=[]
        for t in start_t:
            veh.append(g_df[g_df.starttime==t].vehodo)
        try:
            for i in range(len(veh)-1):
                if int(veh[i+1])-int(veh[i])<=10:
                    vehs.append(int(veh[i+1])-int(veh[i]))
            return len(vehs)
        except:return 2
    
    def max_seq_vehs(self,g_df):
        ttx = np.array(g_df.starttime)
        c = list(np.diff(ttx)/np.timedelta64(1, 's'))
        c.insert(0,1);g_df.loc[:,'temp'] = c
        start_t = g_df[g_df.temp > 10].starttime.tolist()
        if len(start_t) == 0:
            return 0
        elif len(start_t) == 1:
            return 1
        veh = [];vehs=[]
        for t in start_t:
            veh.append(g_df[g_df.starttime==t].vehodo)
        try:
            for i in range(len(veh)-1):
                vehs.append(int(veh[i+1])-int(veh[i]))
            return max(vehs)
        except:return 2
    
    def t_times(self,g_df):
        return (g_df.iloc[-1].starttime - g_df.iloc[0].starttime).total_seconds()/3600
    
    def max_speeds(self,g_df):
        return max(list(g_df.loc[:,'vehspeed']))
    
    def total_time_v1_rpm0s(self,g_df):
        return g_df.loc[(g_df['vehrpm'] == 0)&(g_df['vehspeed'] <= 1)].shape[0]/3600
    
    def total_time_v1_rpm1s(self,g_df):
        return g_df.loc[(g_df['vehrpm'] != 0)&(g_df['vehspeed'] <= 1)].shape[0]/3600
    
    def max_vehrpms(self,g_df):
        return max(list(g_df.loc[:,'vehrpm']))
    
    def t_time_batt12s(self,g_df):
        return g_df.loc[g_df['vehbatt'] <12].shape[0]/3600
    
    def t_time_batt10s(self,g_df):
        return g_df.loc[g_df['vehbatt'] <=10].shape[0]/3600
    
    def t_time_batt14s(self,g_df):
        return g_df.loc[(g_df['vehbatt'] >= 12)&(g_df['vehbatt'] <= 14)].shape[0]/3600
    
    def purchase_times(self,g_df):
        return (g_df.ptime - g_df.starttime)[0].days
    
    def concat_data(self):
        n_power_time_012 = self.day_group.apply(self.n_p_time_012).to_frame(name=self.n_power_time_012)
        n_power_time_12 = self.day_group.apply(self.n_p_time_12).to_frame(name=self.n_power_time_12)
        pm_1 = self.day_group.apply(self.fpm_1).to_frame(name=self.pm_1)
        pm_0 = self.day_group.apply(self.fpm_0).to_frame(name=self.pm_0)
        pm_2 = self.day_group.apply(self.fpm_2).to_frame(name=self.pm_2)
        pm_3 = self.day_group.apply(self.fpm_3).to_frame(name=self.pm_3)
        run_time_2k =  self.day_group.apply(self.run_t_2k).to_frame(name=self.run_time_2k)
        run_time_1k =  self.day_group.apply(self.run_t_1k).to_frame(name=self.run_time_1k)
        run_time_15k =  self.day_group.apply(self.run_t_15k).to_frame(name=self.run_time_15k)
        run_time_25k =  self.day_group.apply(self.run_t_25k).to_frame(name=self.run_time_25k)
        run_time_3k =  self.day_group.apply(self.run_t_3k).to_frame(name=self.run_time_3k)
        num_non_p =  self.day_group.apply(self.num_n_p).to_frame(name=self.num_non_p)
        oil_non_p = self.day_group.apply(self.oil_n_p).to_frame(name=self.oil_non_p)
        battery_start =  self.day_group.apply(self.batt_start).to_frame(name=self.battery_start)
        battery_11 =  self.day_group.apply(self.batt_11).to_frame(name=self.battery_11)
        battery_12 =  self.day_group.apply(self.batt_12).to_frame(name=self.battery_12)
        battery_13 =  self.day_group.apply(self.batt_13).to_frame(name=self.battery_13)
        battery_14 =  self.day_group.apply(self.batt_14).to_frame(name=self.battery_14)
        t_time = self.day_group.apply(self.t_times).to_frame(name=self.t_time)
        oil_start = self.day_group.apply(self.oils_start).to_frame(name=self.oil_start)
        dr_mile30 = self.day_group.apply(self.dr_miles30s).to_frame(name=self.dr_mile30)
        dr_v30_rate = self.day_group.apply(self.dr_v30_rates).to_frame(name=self.dr_v30_rate)    
        battery_avg =  self.day_group.apply(self.batt_avg).to_frame(name=self.battery_avg)
        battery_var =  self.day_group.apply(self.batt_var).to_frame(name=self.battery_var)
        battery_max =  self.day_group.apply(self.batt_max).to_frame(name=self.battery_max)
        battery_mix4 =  self.day_group.apply(self.batt_mix4).to_frame(name=self.battery_mix4)
        battery_mix1 =  self.day_group.apply(self.batt_mix1).to_frame(name=self.battery_mix1)
        battery_min =  self.day_group.apply(self.batt_min).to_frame(name=self.battery_min)
        kurt_v_battery =  self.day_group.apply(self.kurt_v_batterys).to_frame(name=self.kurt_v_battery)
        skew_v_battery =  self.day_group.apply(self.skew_v_batterys).to_frame(name=self.skew_v_battery)
        avg_temperature_in =  self.day_group.apply(self.avg_temp_in).to_frame(name=self.avg_temperature_in)
        avg_temperature_out =  self.day_group.apply(self.avg_temp_out).to_frame(name=self.avg_temperature_out)
        starting_num_day =  self.day_group.apply(self.start_num_day).to_frame(name=self.starting_num_day)
        minutes15_st =  self.day_group.apply(self.min15_st).to_frame(name=self.minutes15_st)
        minutes_30_st = self.day_group.apply(self.max30_st).to_frame(name=self.minutes_30_st)
        remote_boot_times =  self.day_group.apply(self.remote_times).to_frame(name=self.remote_boot_times)
        x_acc =  self.day_group.apply(self.x_ac).to_frame(name=self.x_acc)
        y_acc =  self.day_group.apply(self.y_ac).to_frame(name=self.y_acc)
        z_acc =  self.day_group.apply(self.z_ac).to_frame(name=self.z_acc)
        brakepos_var =  self.day_group.apply(self.brak_var).to_frame(name=self.brakepos_var)
        dr_avg_v =  self.day_group.apply(self.d_avg_v).to_frame(name=self.dr_avg_v)
        dr_avg_mile =  self.day_group.apply(self.d_avg_mile).to_frame(name=self.dr_avg_mile)
        dr_mile50 =  self.day_group.apply(self.dr_miles50s).to_frame(name=self.dr_mile50)
        dr_v0_rate =  self.day_group.apply(self.dr_v0_rates).to_frame(name=self.dr_v0_rate)
        avg_run_times =  self.day_group.apply(self.avg_run_time).to_frame(name=self.avg_run_times)
        ac_on_count =  self.day_group.apply(self.ac_on_counts).to_frame(name=self.ac_on_count)
        ac_auto_on_count =  self.day_group.apply(self.ac_auto_on_counts).to_frame(name=self.ac_auto_on_count)
        fanspeed_avg =  self.day_group.apply(self.fanspeed_avgs).to_frame(name=self.fanspeed_avg)
        fanspeed_var =  self.day_group.apply(self.fanspeed_vars).to_frame(name=self.fanspeed_var)
        d_temp_avg =  self.day_group.apply(self.d_temp_avgs).to_frame(name=self.d_temp_avg)
        c_temp_avg =  self.day_group.apply(self.c_temp_avgs).to_frame(name=self.c_temp_avg)
        side_light_count =  self.day_group.apply(self.side_light_counts).to_frame(name=self.side_light_count)
        dip_light_count =  self.day_group.apply(self.dip_light_counts).to_frame(name=self.dip_light_count)
        main_light_count =  self.day_group.apply(self.main_light_counts).to_frame(name=self.main_light_count)
        wiperswitch_avg =  self.day_group.apply(self.wiperswitch_avgs).to_frame(name=self.wiperswitch_avg)
        oli_box_avg =  self.day_group.apply(self.oli_box_avgs).to_frame(name=self.oli_box_avg)
        cool_avg =  self.day_group.apply(self.cool_avgs).to_frame(name=self.cool_avg)
        mils =  self.day_group.apply(self.milss).to_frame(name=self.mils)
        batt_1 = self.day_group.apply(self.batt_1s).to_frame(name=self.batt_1)
        batt_0 = self.day_group.apply(self.batt_0s).to_frame(name=self.batt_0)
        acc_seqs_min30_0_rate = self.day_group.apply(self.acc_seqs_min30_0_rates).to_frame(name=self.acc_seqs_min30_0_rate)
        acc_seqs_min20_0_rate = self.day_group.apply(self.acc_seqs_min20_0_rates).to_frame(name=self.acc_seqs_min20_0_rate)
        acc_seqs_min10_0_rate = self.day_group.apply(self.acc_seqs_min10_0_rates).to_frame(name=self.acc_seqs_min10_0_rate)
        max_seq_veh = self.day_group.apply(self.max_seq_vehs).to_frame(name=self.max_seq_veh)
        max_speed = self.day_group.apply(self.max_speeds).to_frame(name=self.max_speed)
        total_time_v1_rpm0 = self.day_group.apply(self.total_time_v1_rpm0s).to_frame(name=self.total_time_v1_rpm0)
        total_time_v1_rpm1 = self.day_group.apply(self.total_time_v1_rpm1s).to_frame(name=self.total_time_v1_rpm1)
        max_vehrpm = self.day_group.apply(self.max_vehrpms).to_frame(name=self.max_vehrpm)
        t_time_batt12 = self.day_group.apply(self.t_time_batt12s).to_frame(name=self.t_time_batt12)
        t_time_batt10 = self.day_group.apply(self.t_time_batt10s).to_frame(name=self.t_time_batt10)
        t_time_batt14 = self.day_group.apply(self.t_time_batt14s).to_frame(name=self.t_time_batt14)
        purchase_time = self.day_group.apply(self.purchase_times).to_frame(name=self.purchase_time)
        
        vin_data = pd.concat([n_power_time_012,n_power_time_12,run_time_2k,num_non_p,battery_start,battery_avg,
                              pm_1,pm_0,pm_2,pm_3,run_time_1k,run_time_15k,run_time_25k,run_time_3k,
                              oil_non_p,oil_start,battery_11,battery_12,battery_13,battery_14,minutes_30_st,
                                   battery_var,battery_max,battery_mix4,battery_mix1,battery_min,dr_v30_rate,
                                   kurt_v_battery,skew_v_battery,avg_temperature_in,avg_temperature_out,
                                   starting_num_day,minutes15_st,remote_boot_times,x_acc,y_acc,z_acc,
                                   brakepos_var,dr_avg_v,dr_avg_mile,dr_mile50,dr_v0_rate,dr_mile30,
                                   avg_run_times,ac_on_count,ac_auto_on_count,fanspeed_avg,fanspeed_var,
                                   d_temp_avg,c_temp_avg,side_light_count,dip_light_count,main_light_count,wiperswitch_avg,
                                   acc_seqs_min30_0_rate,acc_seqs_min20_0_rate,acc_seqs_min10_0_rate,
                                   t_time,max_speed,total_time_v1_rpm0,total_time_v1_rpm1,max_vehrpm,t_time_batt12,
                                   t_time_batt10,t_time_batt14,purchase_time,
                                   oli_box_avg,cool_avg,mils,batt_1,batt_0,max_seq_veh],axis=1)
        vin_data = vin_data.fillna(method='pad');vin_data = vin_data.fillna(method='bfill');vin_data = vin_data.sort_index()
        return vin_data




